_require local "../../../../basis.smi"
_require local "../../../libs/config/main/Config.smi"
(* _require local "../../../extensions/debug/main/Bug.smi" *)

_require local "./CoreUtils.smi"
_require local "./TempFile.smi"

_require "./ShellUtils.smi"
_require "./Filename.smi"

structure LLVMUtils =
struct

  val ASMEXT : string
  val OBJEXT : string

  datatype opt_level =
      O0
    | O1
    | O2
    | O3
    | Os
    | Oz

  datatype reloc_model =
      RelocDefault
    | RelocStatic
    | RelocPIC
    | RelocDynamicNoPIC

  datatype file_type =
      AssemblyFile
    | ObjectFile
    | IRFile
    | BitcodeFile

  type compile_options =
      {systemBaseExecDir : Filename.filename,
       triple : string,
       arch : string,
       cpu : string,
       features : string,
       optLevel : opt_level,
       relocModel : reloc_model,
       LLCFLAGS : ShellUtils.arg list,
       OPTFLAGS : ShellUtils.arg list}

  val compile : compile_options
                -> {srcfile: Filename.filename,
                    dstfile: file_type * Filename.filename}
                -> unit

  val assemble : Filename.filename -> Filename.filename

  datatype ty =
      Int
    | Float
    | Vector
    | Aggregate
    | Pointer of int

  type alignment = {ty : ty, size : int, abi : int, prefer : int}

  type data_layout =
      {string : string,
       bigEndian : bool,
       stackAlignment : int,
       allocaAddrSpace : int,
       nativeIntWidths : int list,
       nonIntegralAddrSpaces : int list,
       alignment : alignment list}

  val getDataLayout : compile_options -> data_layout

  val getVersion : unit -> string
  val getDefaultTarget : unit -> string

end
